home *** CD-ROM | disk | FTP | other *** search
- /*
- * File: omisc.r
- * Contents: refresh, size, tabmat, toby, to, llist
- */
-
- "^x - create a refreshed copy of a co-expression."
- #ifdef Coexpr
- /*
- * ^x - return an entry block for co-expression x from the refresh block.
- */
- operator{1} ^ refresh(x)
- if !is:co_expression(x) then
- runerr(118, x)
- abstract {
- return co_expression
- }
-
- body {
- register struct b_coexpr *sblkp;
-
- /*
- * Get a new co-expression stack and initialize.
- */
- Protect(sblkp = alccoexp(), runerr(0));
-
- sblkp->freshblk = BlkLoc(x)->coexpr.freshblk;
- if (ChkNull(sblkp->freshblk)) /* &main cannot be refreshed */
- runerr(215, x);
-
- /*
- * Use refresh block to finish initializing the new co-expression.
- */
- co_init(sblkp);
-
- #if COMPILER
- sblkp->fnc = BlkLoc(x)->coexpr.fnc;
- if (line_info) {
- if (debug_info)
- PFDebug(sblkp->pf)->proc = PFDebug(BlkLoc(x)->coexpr.pf)->proc;
- PFDebug(sblkp->pf)->old_fname =
- PFDebug(BlkLoc(x)->coexpr.pf)->old_fname;
- PFDebug(sblkp->pf)->old_line =
- PFDebug(BlkLoc(x)->coexpr.pf)->old_line;
- }
- #endif /* COMPILER */
-
- return co_expression(sblkp);
- }
- #else /* Coexpr */
- operator{} ^ refresh(x)
- runerr(401)
- #endif /* Coexpr */
-
- end
-
-
- "*x - return size of string or object x."
-
- operator{1} * size(x)
- abstract {
- return integer
- }
- type_case x of {
- string: inline {
- return C_integer StrLen(x);
- }
- list: inline {
- return C_integer BlkLoc(x)->list.size;
- }
- table: inline {
- return C_integer BlkLoc(x)->table.size;
- }
- set: inline {
- return C_integer BlkLoc(x)->set.size;
- }
- cset: inline {
- register word i;
-
- i = BlkLoc(x)->cset.size;
- if (i < 0)
- i = cssize(&x);
- return C_integer i;
- }
- record: inline {
- return C_integer BlkLoc(x)->record.recdesc->proc.nfields;
- }
- co_expression: inline {
- return C_integer BlkLoc(x)->coexpr.size;
- }
- default: {
- /*
- * Try to convert it to a string.
- */
- if !cnv:tmp_string(x) then
- runerr(112, x); /* no notion of size */
- inline {
- return C_integer StrLen(x);
- }
- }
- }
- end
-
-
- "=x - tab(match(x)). Reverses effects if resumed."
-
- operator{*} = tabmat(x)
- /*
- * x must be a string.
- */
- if !cnv:string(x) then
- runerr(103, x)
- abstract {
- return string
- }
-
- body {
- register word l;
- register char *s1, *s2;
- C_integer i, j;
- /*
- * Make a copy of &pos.
- */
- i = k_pos;
-
- /*
- * Fail if &subject[&pos:0] is not of sufficient length to contain x.
- */
- j = StrLen(k_subject) - i + 1;
- if (j < StrLen(x))
- fail;
-
- /*
- * Get pointers to x (s1) and &subject (s2). Compare them on a bytewise
- * basis and fail if s1 doesn't match s2 for *s1 characters.
- */
- s1 = StrLoc(x);
- s2 = StrLoc(k_subject) + i - 1;
- l = StrLen(x);
- while (l-- > 0) {
- if (*s1++ != *s2++)
- fail;
- }
-
- /*
- * Increment &pos to tab over the matched string and suspend the
- * matched string.
- */
- l = StrLen(x);
- k_pos += l;
- suspend x;
-
- /*
- * tabmat has been resumed, restore &pos and fail.
- */
- if (i > StrLen(k_subject) + 1)
- runerr(205, kywd_pos);
- else
- k_pos = i;
- fail;
- }
- end
-
-
- "i to j by k - generate successive values."
-
- operator{*} ... toby(from, to, by)
- /*
- * arguments must be integers.
- */
- if !cnv:C_integer(from) then
- runerr(101, from)
- if !cnv:C_integer(to) then
- runerr(101, to)
- if !cnv:C_integer(by) then
- runerr(101, by)
-
- abstract {
- return integer
- }
-
- inline {
- /*
- * by must not be zero.
- */
- if (by == 0) {
- irunerr(211, by);
- errorfail;
- }
-
- /*
- * Count up or down (depending on relationship of from and to) and
- * suspend each value in sequence, failing when the limit has been
- * exceeded.
- */
- if (by > 0)
- for ( ; from <= to; from += by) {
- suspend C_integer from;
- }
- else
- for ( ; from >= to; from += by) {
- suspend C_integer from;
- }
- fail;
- }
- end
-
-
- "i to j - generate successive values."
-
- operator{*} ... to(from, to)
- /*
- * arguments must be integers.
- */
- if !cnv:C_integer(from) then
- runerr(101, from)
- if !cnv:C_integer(to) then
- runerr(101, to)
-
- abstract {
- return integer
- }
-
- inline {
- for ( ; from <= to; ++from) {
- suspend C_integer from;
- }
- fail;
- }
- end
-
-
- " [x1, x2, ... ] - create an explicitly specified list."
-
- operator{1} [...] llist(elems[n])
- abstract {
- return new list(type(elems))
- }
- body {
- tended struct b_list *hp;
- register word i;
- register struct b_lelem *bp; /* need not be tended */
- word nslots;
-
- nslots = n;
- if (nslots == 0)
- nslots = MinListSlots;
-
- /*
- * Allocate the list and a list block.
- */
- Protect(hp = alclist(n), runerr(0));
- Protect(bp = alclstb(nslots, (word)0, n), runerr(0));
-
- /*
- * Make the list block just allocated into the first and last blocks
- * for the list.
- */
- hp->listhead = hp->listtail = (union block *)bp;
-
- /*
- * Assign each argument to a list element.
- */
- for (i = 0; i < n; i++)
- bp->lslots[i] = elems[i];
-
- return list(hp);
- }
- end
-
-